<?php

/* Id */

require_once 'view.php';
require_once 'q/request.php';


class q_mvc_controller {

    public static $_instance = null;

    public $params = array(
        'module' => 'default',
        'action' => 'index',
    );

    public $view;

    public $hasNextAction;

    public static function getInstance(){
        if(empty(self::$_instance)){
            self::$_instance = new q_mvc_controller();
        }
        return self::$_instance;
    }

    public function setHasNextAction(){
        $this->hasNextAction = true;
    }

    public function run(){

        $this->parseParams();

        $this->view = new q_mvc_view();
        $this->view->setController($this);

        $loops = 0;
        do{
            $loops++;
            if($loops > 10){
                $this->error('too many loops');
            }

            $this->hasNextAction = false;

            $this->loadAction();

        }while($this->hasNextAction);

        $this->view->output();
    }

    public function loadAction(){
        $fileName = $this->getActionFile();

        if(file_exists($fileName)){
            require_once $fileName;
            $className = $this->getActionClass();

            if(class_exists($className)){

                $module = new $className;
                $module->setController($this);
                $module->setView($this->view);

                $actionMethod = $this->getActionMethod();

                if(method_exists($module, $actionMethod)){
                    $tpl = 'template/' . $this->params['module'] . '_' . $this->params['action'] . '.phtml';

                    $this->view->setTemplate($tpl);
                    $module->init();
                    $module->$actionMethod();
                } else {
                    $this->error('method not exists', $actionMethod);
                }

            } else {
                $this->error('class not exists', $className);
            }

        } else {
            $this->error('module not found', $fileName);
        }
    }

    public function error($msg = '', $arg = ''){

        error_log("Controller: " . $msg . " " . $arg);

        echo $msg;

        exit;
    }

    public function getActionFile(){
        return 'action/'.$this->params['module'].'.php';
    }

    public function getActionClass(){
        $module = $this->params['module'];
        if(ctype_alnum($module) and ctype_alpha($module[0])){
            return 'action_'.strtolower($module);
        } else {
            $this->error('bad class name', $module);
        }
    }

    public function getActionMethod(){
        $action = $this->params['action'];
        if(ctype_alnum($action) and ctype_alpha($action[0])){
            return strtolower($action).'Action';
        } else {
            $this->error('bad action name', $action);
        }
    }

    public function parseParams(){
        if(!empty($_GET['module'])){
            $this->setModule($_GET['module']);
        }
        if(!empty($_GET['action'])){
            $this->setAction($_GET['action']);
        }
    }

    public function setAction($action){
        $this->setHasNextAction();
        $this->params['action'] = $action;
    }

    public function setModule($module){
        $this->params['module'] = $module;
    }
}


